﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
using System.IO;
using System.Threading;


namespace Smoke
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }
        private AutoWindowsize autowindowsize;
        private VisionSet mVisionSet;
        public HObject ho_Image = null;
        public HTuple hv_AcqHandle = null;
        public HTuple width, height;
        public HTuple hv_WindowHandle;
        public bool iscamopen = false;
        public bool camOrfile = false;
        private HTuple hv_MLPHandle;
        private HTuple hv_FileName;
        private List<string> list = new List<string>();
        private int hv_Index = 0;
        private HTuple hv_AllDir;
        public string imagepath;
        public HTuple hv_GoodDir;
        public HTuple hv_imgeIndex = 0;

        public HTuple GetAllDir
        {
            get
            {
                hv_AllDir = System.Environment.CurrentDirectory;
                return hv_AllDir;
            }
        }
        public HTuple HalconWindowID { get { return Display.HalconWindow; } }

        public bool videostart { get; private set; }

        private void CreateHalconWindow()
        {
            try
            {
                if (hv_WindowHandle != null) { HOperatorSet.CloseWindow(hv_WindowHandle); hv_WindowHandle = null; }
                if (Display.Width>0&& Display.Height>0)
                {
                    HOperatorSet.OpenWindow(0, 0, Display.Width, Display.Height, HalconWindowID, "visible", "", out hv_WindowHandle);
                   
                   

                }

            }
            catch (Exception)
            {

                return;
            }

        }
        public void DisplyImage()
        {
            try
            {
                HOperatorSet.SetPart(hv_WindowHandle, 0, 0, height, width);
                HOperatorSet.DispObj(ho_Image, hv_WindowHandle);
            }
            catch (Exception)
            {

                return;
            }

        }

        public void set_display_font(HTuple hv_WindowHandle, HTuple hv_Size, HTuple hv_Font,
     HTuple hv_Bold, HTuple hv_Slant)
        {


            HTuple hv_OS = null, hv_Fonts = new HTuple();
            HTuple hv_Style = null, hv_Exception = new HTuple(), hv_AvailableFonts = null;
            HTuple hv_Fdx = null, hv_Indices = new HTuple();
            HTuple hv_Font_COPY_INP_TMP = hv_Font.Clone();
            HTuple hv_Size_COPY_INP_TMP = hv_Size.Clone();


            //
            HOperatorSet.GetSystem("operating_system", out hv_OS);

            if ((int)((new HTuple(hv_Size_COPY_INP_TMP.TupleEqual(new HTuple()))).TupleOr(
                new HTuple(hv_Size_COPY_INP_TMP.TupleEqual(-1)))) != 0)
            {
                hv_Size_COPY_INP_TMP = 16;
            }
            if ((int)(new HTuple(((hv_OS.TupleSubstr(0, 2))).TupleEqual("Win"))) != 0)
            {
                //Restore previous behaviour
                hv_Size_COPY_INP_TMP = ((1.13677 * hv_Size_COPY_INP_TMP)).TupleInt();
            }
            else
            {
                hv_Size_COPY_INP_TMP = hv_Size_COPY_INP_TMP.TupleInt();
            }
            if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("Courier"))) != 0)
            {
                hv_Fonts = new HTuple();
                hv_Fonts[0] = "Courier";
                hv_Fonts[1] = "Courier 10 Pitch";
                hv_Fonts[2] = "Courier New";
                hv_Fonts[3] = "CourierNew";
                hv_Fonts[4] = "Liberation Mono";
            }
            else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("mono"))) != 0)
            {
                hv_Fonts = new HTuple();
                hv_Fonts[0] = "Consolas";
                hv_Fonts[1] = "Menlo";
                hv_Fonts[2] = "Courier";
                hv_Fonts[3] = "Courier 10 Pitch";
                hv_Fonts[4] = "FreeMono";
                hv_Fonts[5] = "Liberation Mono";
            }
            else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("sans"))) != 0)
            {
                hv_Fonts = new HTuple();
                hv_Fonts[0] = "Luxi Sans";
                hv_Fonts[1] = "DejaVu Sans";
                hv_Fonts[2] = "FreeSans";
                hv_Fonts[3] = "Arial";
                hv_Fonts[4] = "Liberation Sans";
            }
            else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("serif"))) != 0)
            {
                hv_Fonts = new HTuple();
                hv_Fonts[0] = "Times New Roman";
                hv_Fonts[1] = "Luxi Serif";
                hv_Fonts[2] = "DejaVu Serif";
                hv_Fonts[3] = "FreeSerif";
                hv_Fonts[4] = "Utopia";
                hv_Fonts[5] = "Liberation Serif";
            }
            else
            {
                hv_Fonts = hv_Font_COPY_INP_TMP.Clone();
            }
            hv_Style = "";
            if ((int)(new HTuple(hv_Bold.TupleEqual("true"))) != 0)
            {
                hv_Style = hv_Style + "Bold";
            }
            else if ((int)(new HTuple(hv_Bold.TupleNotEqual("false"))) != 0)
            {
                hv_Exception = "Wrong value of control parameter Bold";
                throw new HalconException(hv_Exception);
            }
            if ((int)(new HTuple(hv_Slant.TupleEqual("true"))) != 0)
            {
                hv_Style = hv_Style + "Italic";
            }
            else if ((int)(new HTuple(hv_Slant.TupleNotEqual("false"))) != 0)
            {
                hv_Exception = "Wrong value of control parameter Slant";
                throw new HalconException(hv_Exception);
            }
            if ((int)(new HTuple(hv_Style.TupleEqual(""))) != 0)
            {
                hv_Style = "Normal";
            }
            HOperatorSet.QueryFont(hv_WindowHandle, out hv_AvailableFonts);
            hv_Font_COPY_INP_TMP = "";
            for (hv_Fdx = 0; (int)hv_Fdx <= (int)((new HTuple(hv_Fonts.TupleLength())) - 1); hv_Fdx = (int)hv_Fdx + 1)
            {
                hv_Indices = hv_AvailableFonts.TupleFind(hv_Fonts.TupleSelect(hv_Fdx));
                if ((int)(new HTuple((new HTuple(hv_Indices.TupleLength())).TupleGreater(0))) != 0)
                {
                    if ((int)(new HTuple(((hv_Indices.TupleSelect(0))).TupleGreaterEqual(0))) != 0)
                    {
                        hv_Font_COPY_INP_TMP = hv_Fonts.TupleSelect(hv_Fdx);
                        break;
                    }
                }
            }
            if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual(""))) != 0)
            {
                throw new HalconException("Wrong value of control parameter Font");
            }
            hv_Font_COPY_INP_TMP = (((hv_Font_COPY_INP_TMP + "-") + hv_Style) + "-") + hv_Size_COPY_INP_TMP;
            HOperatorSet.SetFont(hv_WindowHandle, hv_Font_COPY_INP_TMP);
            // dev_set_preferences(...); only in hdevelop

            return;
        }
        public void DisText(HTuple windhand, HTuple size, HTuple row, HTuple column, String color, String text)
        {
            set_display_font(windhand, size, "mono", "true", "false");
            HOperatorSet.SetTposition(windhand, row, column);
            HOperatorSet.SetColor(windhand, color);
            HOperatorSet.WriteString(windhand, text);
        }


        public void Director(string dir, List<string> list)
        {
            DirectoryInfo d = new DirectoryInfo(dir);
            FileInfo[] files = d.GetFiles();//文件
            DirectoryInfo[] directs = d.GetDirectories();//文件夹

            foreach (FileInfo f in files)
            {
                list.Add(f.Name);
            }

        }
        public void LoadImage()
        {
            if (rdnCam.Checked)
            {
                try
                {
                    if (OpenCam())
                    //set_framegrabber_param (AcqHandle, 'contrast', 172)
                    {

                        HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
                    }

                    else
                    {
                        MessageBox.Show("打开相机失败");
                        return;
                    }
                }
                catch (Exception)
                {

                    MessageBox.Show("打开相机失败");
                }

            }
            else
            {



                if (list.Count < 1)
                    Director(imagepath, list);
                if (hv_Index >= list.Count)
                    hv_Index = 0;
                hv_FileName = imagepath + "/" + list[hv_Index];
                hv_Index++;
                ho_Image.Dispose();
                HOperatorSet.ReadImage(out ho_Image, hv_FileName);

            }

        }
        private bool OpenCam()
        {
            try
            {
                if (!iscamopen)
                {
                    // Initialize local and output iconic variables 
                    HOperatorSet.GenEmptyObj(out ho_Image);
                    //HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
                    // -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_AcqHandle);
                    HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
                        -1, "false", "default", "[0] Hengal USB", 0, -1, out hv_AcqHandle);
                    //HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "contrast", 180);
                    //  HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "brightness", 80);
                    HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
                    ho_Image.Dispose();
                    HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
                    HOperatorSet.GetImageSize(ho_Image, out width, out height);
                    iscamopen = true;
                }
                return iscamopen;
            }
            catch (Exception)
            {
                iscamopen = false;
                MessageBox.Show("相机打开失败");
                return false;
            }

        }
        private void CloseCam()
        {
            if (iscamopen)
            {
                HOperatorSet.CloseFramegrabber(hv_AcqHandle);
                ho_Image.Dispose();

            }

        }

        private void btn_Test_Click(object sender, EventArgs e)
        {
            HObject Rectangle;
            HTuple LineAngle;
            HTuple RectNum = 0;
            HTuple length,Sortlen, MeanLen;
            HTuple RectAngle,deg;
            HTuple area, row, column, sortedeg, abs;
            if (iscamopen)
            {
                try
                {

                    LoadImage();
                    if (hv_WindowHandle!=null)
                    
                    HOperatorSet.ClearWindow(hv_WindowHandle);
                    DisplyImage();
                    ImageProcessing(ho_Image,  out Rectangle, out  LineAngle);
                    HOperatorSet.SetDraw(hv_WindowHandle, "margin");
                    HOperatorSet.SetColor(hv_WindowHandle, "red");
                    HOperatorSet.DispObj(Rectangle,hv_WindowHandle);
                    HOperatorSet.CountObj(Rectangle, out RectNum);
                    HOperatorSet.RegionFeatures(Rectangle, "rect2_len1", out length);
                    HOperatorSet.TupleSort(length, out Sortlen);
                    HOperatorSet.TupleMean(Sortlen, out MeanLen);
                    HOperatorSet.OrientationRegion(Rectangle, out RectAngle);
                    HOperatorSet.TupleDeg(RectAngle, out deg);
                    HOperatorSet.AreaCenter(Rectangle, out area, out row, out column);
                    HOperatorSet.TupleAbs(deg,out abs);
                    HOperatorSet.TupleSort(abs, out sortedeg);
                    StreamWriter sw = new StreamWriter(@"D:\\123.txt", true, Encoding.ASCII);
                    sw.Write(sortedeg.ToString() + "\r\n");
                    sw.Write(row.ToString() + "\r\n");
                    sw.Write(column.ToString() + "\r\n");
                    sw.Flush();
                    sw.Close();

                    if (RectNum == 9 && LineAngle >Convert.ToInt32(VisionSet.Instance.txbMinDeg.Text) && LineAngle 
                        <Convert.ToInt32(VisionSet.Instance.txbMaxDeg.Text) && Sortlen[0]> Convert.ToDouble(VisionSet.Instance.txbRate.Text) * MeanLen)
                        DisText(hv_WindowHandle, 120, 120, 100, "green", "PASS");
                    else
                        DisText(hv_WindowHandle, 120, 120, 100, "red", "NG");
                }
                catch (Exception)
                {

                    return;
                }
            }


        }

        private void ImageProcessing(HObject Img, out HObject ho_Rectangle1, out HTuple angle)
        {
            ho_Rectangle1 = null;
            angle = 0;

            if (Img != null)
            { 
                HObject ho_GrayImage = null, ho_circle = null;
                HObject ho_ImageReduced = null, ho_Region = null, ho_RegionClosing = null;
                HObject ho_ConnectedRegions1 = null, ho_SelectedRegions = null;
                HObject ho_RegionFillUp = null, ho_RegionTrans = null, ho_ImageReduced4 = null;
                HObject ho_Contours = null, ho_ContoursSplit = null, ho_ObjectSelected = null;
                HObject ho_Region2 = null, ho_ObjectSelected1 = null, ho_Rectangle = null;
                HObject ho_ImageReduced3 = null, ho_RegionErosion = null, ho_RegionDifference = null;
                HObject ho_ImageReduced2 = null, ho_RegionDifference1 = null;
                HObject ho_ImageReduced1 = null, ho_Region1 = null, ho_RegionOpening = null;
                HObject ho_RegionFillUp1 = null, ho_RegionBorder = null, ho_Contours1 = null;
                HTuple hv_Width = new HTuple();
                HTuple hv_Height = new HTuple();
                HTuple hv_Number = new HTuple(), hv_Sorted1 = new HTuple();
                HTuple hv_Length = new HTuple();
                HTuple  hv_Index1 = new HTuple();
                HTuple hv_Phi = new HTuple(), hv_Deg = new HTuple();
                HTuple hv_maxcontors = new HTuple(), hv_Area = new HTuple(), hv_Abs = new HTuple();
                HTuple hv_Row = new HTuple(), hv_Column = new HTuple();
                HTuple hv_Row1 = new HTuple(), hv_Column1 = new HTuple();
                HTuple hv_Phi1 = new HTuple(), hv_Length1 = new HTuple();
                HTuple hv_Length2 = new HTuple(), hv_PointOrder = new HTuple();
                HTuple hv_Sorted = new HTuple(), hv_Mean = new HTuple();
                int hv_maxindex;
                // Initialize local and output iconic variables 
                try
                {

                    HOperatorSet.AccessChannel(Img, out ho_GrayImage, 3);
                    //rgb1_to_gray (Image, GrayImage)
                    HOperatorSet.GenCircle(out ho_circle, 200, 160, 150);
                    HOperatorSet.ReduceDomain(ho_GrayImage, ho_circle, out ho_ImageReduced);
                    HOperatorSet.Threshold(ho_ImageReduced, out ho_Region, 0, 60);
                    HOperatorSet.ClosingCircle(ho_Region, out ho_RegionClosing, 3.5);
                    HOperatorSet.Connection(ho_RegionClosing, out ho_ConnectedRegions1);
                    HOperatorSet.SelectShape(ho_ConnectedRegions1, out ho_SelectedRegions, "area", "and", 1500, 99999);
                    HOperatorSet.FillUp(ho_SelectedRegions, out ho_RegionFillUp);
                    //blob 抠出ROI区域
                    HOperatorSet.ShapeTrans(ho_RegionFillUp, out ho_RegionTrans, "convex");
                    HOperatorSet.ReduceDomain(ho_ImageReduced, ho_RegionTrans, out ho_ImageReduced4);
                    //求出边缘contour
                    HOperatorSet.GenContourRegionXld(ho_RegionTrans, out ho_Contours, "border");
                    HOperatorSet.SegmentContoursXld(ho_Contours, out ho_ContoursSplit, "lines", 5, 4, 2);
                    HOperatorSet.CountObj(ho_ContoursSplit, out hv_Number);
                    //排序找到最长直线
                    hv_Sorted1 = new HTuple();
                    HOperatorSet.LengthXld(ho_ContoursSplit, out hv_Length);
                    HOperatorSet.TupleSort(hv_Length, out hv_Sorted1);
                    hv_maxindex = hv_Number[0].I;
                   
                    for (int i = hv_maxindex; i > 0; i--)
                    {
                        HTuple end_val36 = hv_Number;
                        HTuple step_val36 = 1;
                        HTuple tem = (hv_Sorted1[hv_maxindex - 1]);
                        for (hv_Index1 = 1; hv_Index1.Continue(end_val36, step_val36); hv_Index1 = hv_Index1.TupleAdd(step_val36))
                        {
                            HOperatorSet.SelectObj(ho_ContoursSplit, out ho_ObjectSelected, hv_Index1);
                            HOperatorSet.LengthXld(ho_ObjectSelected, out hv_Length);

                            if (hv_Sorted1[i-1].D == hv_Length[0].D)
                            {
                                HOperatorSet.GenRegionContourXld(ho_ObjectSelected, out ho_Region2, "filled");
                                HOperatorSet.OrientationRegion(ho_Region2, out hv_Phi);
                                HOperatorSet.TupleDeg(hv_Phi, out hv_Deg);
                                if (hv_Deg[0].D < 0)
                                    angle = hv_Deg + 180;
                                else angle = hv_Deg;
                               //确认是否最长直线
                                if (Convert.ToDouble(VisionSet.Instance.txbMinDeg.Text) < angle[0].D && Convert.ToDouble(VisionSet.Instance.txbMaxDeg.Text) > angle[0].D)
                                {
                                    hv_maxcontors = hv_Index1.Clone();
                                    i = 0;
                                    break;
                                }
                            }
                        }
                        
                    }
     
                    HOperatorSet.SelectObj(ho_ContoursSplit, out ho_ObjectSelected1, hv_maxcontors);
                    HOperatorSet.GenRegionContourXld(ho_ObjectSelected1, out ho_Region2, "filled");
                    HOperatorSet.OrientationRegion(ho_Region2, out hv_Phi);
                    HOperatorSet.TupleDeg(hv_Phi, out hv_Deg);
                    //求出直线中心
                    HOperatorSet.AreaCenterPointsXld(ho_ObjectSelected1, out hv_Area, out hv_Row,out hv_Column);
                    HOperatorSet.GenRectangle2(out ho_Rectangle, hv_Row, hv_Column, hv_Phi, 150,23);
                    HOperatorSet.ReduceDomain(ho_ImageReduced4, ho_Rectangle, out ho_ImageReduced3);
                    HOperatorSet.ErosionCircle(ho_ImageReduced4, out ho_RegionErosion, Convert.ToInt32(VisionSet.Instance.txbRoiWidth.Text));
                    //减点直线部分区域
                    HOperatorSet.Difference(ho_ImageReduced4, ho_RegionErosion, out ho_RegionDifference);
                    HOperatorSet.ReduceDomain(ho_ImageReduced4, ho_RegionDifference, out ho_ImageReduced2);
                    HOperatorSet.Difference(ho_ImageReduced2, ho_ImageReduced3, out ho_RegionDifference1 );
                    HOperatorSet.ReduceDomain(ho_ImageReduced4, ho_RegionDifference1, out ho_ImageReduced1);
                    HOperatorSet.Threshold(ho_ImageReduced1, out ho_Region1, Convert.ToInt32(VisionSet.Instance.txbMinGray.Text), 200);
                    HOperatorSet.OpeningCircle(ho_Region1, out ho_RegionOpening, 3);
                    HOperatorSet.FillUp(ho_RegionOpening, out ho_RegionFillUp1);
                    HOperatorSet.Boundary(ho_RegionFillUp1, out ho_RegionBorder, "outer");
                    HOperatorSet.GenContourRegionXld(ho_RegionBorder, out ho_Contours1, "border");
                    HOperatorSet.FitRectangle2ContourXld(ho_Contours1, "regression", -1, 0, 0,
                        3, 2, out hv_Row1, out hv_Column1, out hv_Phi1, out hv_Length1, out hv_Length2, out hv_PointOrder);
                    HOperatorSet.GenRectangle2(out ho_Rectangle1, hv_Row1, hv_Column1, hv_Phi1, hv_Length1, hv_Length2);
                    

                }
                catch (Exception)
                {
                    
                    return;
                }
            }
        }
            private void Form1_SizeChanged(object sender, EventArgs e)
            {
           autowindowsize.FormSizeChange();
            CreateHalconWindow();
        }

            private void Form1_Load(object sender, EventArgs e)

            {
                autowindowsize = new AutoWindowsize(this);
                imagepath = GetAllDir + "\\all";
                //HOperatorSet.ReadClassMlp(GetAllDir + "\\sample.gmc", out hv_MLPHandle);
                mVisionSet= VisionSet.Instance;
               mVisionSet.txbRoiWidth.Text = JosnConfig.ReadConfig("Roi宽度");
               mVisionSet.txbMinGray.Text = JosnConfig.ReadConfig("MinGray");
               mVisionSet.txbRate.Text = JosnConfig.ReadConfig("引脚间隙比率");
               mVisionSet.txbMaxDeg.Text = JosnConfig.ReadConfig("开口角度最大值");
               mVisionSet.txbMinDeg.Text = JosnConfig.ReadConfig("开口角度最小值");
        }

            private void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                CloseCam();
            }

            private void btnfiledir_Click(object sender, EventArgs e)
            {
            FolderBrowserDialog mopenFileDir = new FolderBrowserDialog();
                if (mopenFileDir.ShowDialog() == DialogResult.OK)
                {
                hv_AllDir = mopenFileDir.SelectedPath;
                }

            }

            private void button1_Click(object sender, EventArgs e)
            {
                HTuple hv_FilePath;
                hv_GoodDir = hv_AllDir;
                if (iscamopen)
                {
                    HOperatorSet.GrabImage(out ho_Image, hv_AcqHandle);
                    //Image Acquisition 01: Do something
                    hv_FileName = (hv_imgeIndex.TupleString(".3")) + ".bmp";
                    hv_FilePath = hv_GoodDir + "/" + hv_FileName;
                    HOperatorSet.WriteImage(ho_Image, "bmp", 0, hv_FilePath);
                    hv_imgeIndex = hv_imgeIndex + 1;
                }
            }

            private void ckbvideo_CheckedChanged(object sender, EventArgs e)
            {
                if (ckbvideo.Checked)
                {
                    Thread videoth = new Thread(statartVideo);
                    videoth.IsBackground = true;
                    videoth.Start();
                    videostart = true;
                }
                else
                {
                    videostart = false;

                }

            }

            private void statartVideo()
            {
                while (videostart && iscamopen)
                {
                    LoadImage();
                    DisplyImage();
                }
            }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            
        }

        private void 参数设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            mVisionSet.StartPosition = FormStartPosition.CenterScreen;
            mVisionSet.ShowDialog();
        }

        private void Btn_OpenCam_Click(object sender, EventArgs e)
            {
                try
                {
                    if (!iscamopen)
                    {
                        OpenCam();
                        CreateHalconWindow();
                        DisplyImage();
                    }

                }
                catch (Exception)
                {

                    return;
                }


            }
        }

    }
